package com.gaeainfo.modules.base.dao;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Caven on 2018/1/12.
 */
@Repository
public class BaseHibernateDao {

    private HibernateTemplate hibernateTemplate;

    private SessionFactory sessionFactory;

    public SessionFactory getSessionFactory() {
        return this.sessionFactory;
    }

    public HibernateTemplate getHibernateTemplate() {
        return this.hibernateTemplate;
    }

    public Session getSession() {
        return this.getSessionFactory().getCurrentSession();
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
        this.hibernateTemplate = new HibernateTemplate(this.sessionFactory);
        this.hibernateTemplate.setCacheQueries(true);
    }

    /**
     * 添加
     */
    public void save(Object entity) {
        this.hibernateTemplate.save(entity);
    }

    /**
     * 更新
     */
    public void update(Object entity) {
        this.hibernateTemplate.update(entity);
    }

    /**
     * 删除
     */
    public void delete(Object entity) {
        this.hibernateTemplate.delete(entity);
    }

    /**
     * 加载全部
     */
    public <T> List<T> loadAll(Class<T> clazz) {
        return this.hibernateTemplate.loadAll(clazz);
    }

    /**
     * 根据主键加载实体，实体不存在抛出ObjectNotFoundException
     */
    public <T> T load(Class<T> clazz, Serializable id) {
        return hibernateTemplate.load(clazz, id);
    }

    /**
     * 根据主键获取实体，实体不存在抛出NullPointException
     */
    public <T> T get(Class<T> clazz, Serializable id) {
        return this.hibernateTemplate.get(clazz, id);
    }

    /**
     * 检索符合条件的实体
     */
    public List findByCriteria(final DetachedCriteria criteria) {
        return this.hibernateTemplate.findByCriteria(criteria);
    }

    /**
     * 检索符合条件和范围的实体
     */
    public List findByCriteria(final DetachedCriteria criteria, final int firstResult, final int maxResults) {
        return this.hibernateTemplate.findByCriteria(criteria, firstResult, maxResults);
    }

    /**
     * 获取数据总数
     */
    public Integer findDataTotal(final String sql, Map<String, Object> params) {
        Query query = this.getSession().createSQLQuery(sql);
        this.setParams(query, params);
        return Integer.parseInt(query.list().get(0).toString());
    }

    /**
     * 设置Query参数
     */
    public void setParams(Query query, Map<String, Object> params) {
        for (String key : params.keySet()) {
            if (params.get(key) instanceof ArrayList) {
                query.setParameterList(key, (ArrayList) params.get(key));
            } else {
                query.setParameter(key, params.get(key));
            }
        }
    }

    /**
     * 获取数据通过HQL
     */
    public  <T> List<T> findByHql(final String hql, Map<String, Object> params,Class<T> clazz) {
        Query query = this.getSession().createQuery(hql);
        this.setParams(query, params);
        query.setResultTransformer(Transformers.aliasToBean(clazz));
        return query.list();
    }

    /**
     * 获取数据通过HQL
     */
    public List<Map<String,Object>> findByHql(final String hql, Map<String, Object> params) {
        Query query = this.getSession().createQuery(hql);
        this.setParams(query, params);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query.list();
    }

    /**
     * 获取数据实体通过SQL
     */
    public <T> List<T> findBySql(final String sql, Map<String, Object> params, Class<T> clazz) {
        Query query = this.getSession().createSQLQuery(sql);
        this.setParams(query, params);
        query.setResultTransformer(Transformers.aliasToBean(clazz));
        return query.list();
    }

    /**
     * 获取数据通过SQL
     */
    public List<Map<String,Object>> findBySql(final String sql, Map<String, Object> params) {
        Query query = this.getSession().createSQLQuery(sql);
        this.setParams(query, params);
        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query.list();
    }

    /**
     * sql执行更新，删除，添加
     */
    private int execUpdateBySql(final String sql, Map<String, Object> params) {
        Query query = this.getSession().createSQLQuery(sql);
        this.setParams(query, params);
        return query.executeUpdate();
    }

    /**
     * sql添加
     */
    public int save(final String sql, Map<String, Object> params) {
        return this.execUpdateBySql(sql, params);
    }

    /**
     * sql更新
     */
    public int update(final String sql, Map<String, Object> params) {
        return this.execUpdateBySql(sql, params);
    }

    /**
     * sql删除
     */
    public int delete(final String sql, Map<String, Object> params) {
        return this.execUpdateBySql(sql, params);
    }

}
